package com.winspread.ui.dialog

import android.app.Dialog
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.text.TextUtils
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.annotation.LayoutRes
import androidx.annotation.StyleRes
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import com.winspread.ui.R
import com.winspread.ui.databinding.DialogBaseBinding

/**
 *Author: Amin
 *Data: 2021/9/28 9:51
 *
 *Description:  dialog 弹窗
 *
 */
class BaseDialog() : DialogFragment() {

    companion object {
        const val BASE_DIALOG_TAG = "BASE_DIALOG"
        private var mFragment: FragmentManager? = null
        private var mBuildMethod: ((Dialog?, View?) -> Unit)? = null
        private var mDismissMethod: (() -> Unit)? = null
        private var mNegativeButtonMethod: ((Dialog?, View?) -> Unit)? = null
        private var mPositiveButtonMethod: ((Dialog?, View?) -> Unit)? = null
    }


    private var mLayoutRes: Int = 0
    private var mWidth: Int = 0
    private var mHeight: Int = 0
    private var mAnimRes: Int = 0
    private var mTitle: String? = null
    private var mLeftTitle = false
    private var mMessage: String? = null
    private var mNegativeToDismiss = true
    private var mNegativeVis = false
    private var mCanceledOnTouchOutside = false
    private var mBuildMethodAdded = false
    private var mDismissMethodAdded = false
    private var mNegativeButtonMethodAdded = false
    private var mPositiveButtonMethodAdded = false
    private var binding: DialogBaseBinding? = null

    private val mButtonHandler =
        View.OnClickListener { view ->
            if (view === binding!!.btnDialogCancel) {
                if (mNegativeToDismiss) dismiss()
                if (mNegativeButtonMethodAdded) {
                    mNegativeButtonMethod?.run {
                        invoke(dialog, getBaseView())
                    }
                }
            } else if (view === binding!!.btnDialogOk || view === binding!!.btnSimDialogOk) {
                if (mPositiveButtonMethodAdded) {
                    mPositiveButtonMethod?.run {
                        invoke(dialog, getBaseView())
                    }
                }
            }
        }

    init {
        arguments = Bundle()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.run {
            mWidth = getInt("mWidth")
            mHeight = getInt("mHeight")
            mTitle = getString("mTitle")
            mLeftTitle = getBoolean("mLeftTitle")
            mMessage = getString("mMessage")
            mNegativeToDismiss = getBoolean("mNegativeToDismiss", true)
            mCanceledOnTouchOutside = getBoolean("mCanceledOnTouchOutside")
            mBuildMethodAdded = getBoolean("mBuildMethodAdded")
            mDismissMethodAdded = getBoolean("mDismissMethodAdded")
            mNegativeButtonMethodAdded = getBoolean("mNegativeButtonMethodAdded")
            mPositiveButtonMethodAdded = getBoolean("mPositiveButtonMethodAdded")
            mNegativeVis = getBoolean("mNegativeVis")
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.dialog_base, container, false)
        binding = DataBindingUtil.bind(view)
        if (mLayoutRes > 0) {
            val contentView = inflater.inflate(mLayoutRes, null, false)
            (view.findViewById<LinearLayout>(R.id.ll_dialog_custom) as ViewGroup).addView(contentView, 0)
        }
        isCancelable = true
        dialog?.run {
            setCanceledOnTouchOutside(mCanceledOnTouchOutside)
        }
        if (mBuildMethodAdded) {
            mBuildMethod?.run {
                invoke(dialog, view)
            }
        }
        return view
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val showTitle = !TextUtils.isEmpty(mTitle)
        val showMessage = !TextUtils.isEmpty(mMessage)
        if (showTitle) {
            binding!!.tvDialogLeftTitle.text = mTitle
            binding!!.tvDialogTitleOnly.text = mTitle
            binding!!.tvDialogLeftTitle.visibility = if (mLeftTitle) View.VISIBLE else View.GONE
            binding!!.tvDialogTitleOnly.visibility = if (mLeftTitle) View.GONE else View.VISIBLE
        } else {
            binding!!.tvDialogLeftTitle.visibility = View.GONE
            binding!!.tvDialogTitleOnly.visibility = View.GONE
        }
        binding!!.bitOne.visibility = if (mNegativeVis) View.VISIBLE else View.GONE
        binding!!.btnTwo.visibility = if (mNegativeVis) View.GONE else View.VISIBLE
        if (showMessage) binding!!.tvDialogMessage.text = mMessage
        binding!!.tvDialogMessage.visibility = if (showMessage) View.VISIBLE else View.GONE
        binding!!.btnDialogCancel.setOnClickListener(mButtonHandler)
        binding!!.btnDialogOk.setOnClickListener(mButtonHandler)
        binding!!.btnSimDialogOk.setOnClickListener(mButtonHandler)
    }

    override fun onStart() {
        super.onStart()
        val dialog = dialog ?: return
        val window = dialog.window ?: return
        val params = window.attributes
        // 设置背景色透明
        window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        // 设置Dialog动画效果
        if (mAnimRes > 0) window.setWindowAnimations(mAnimRes)
        // 设置Dialog的宽高度
        if (mWidth > 0) params.width = mWidth
        if (mHeight > 0) params.height = mHeight
        // 设置屏幕透明度 0.0f~1.0f(完全透明~完全不透明)
        params.dimAmount = 0.4f
        params.gravity = Gravity.CENTER
        window.attributes = params
    }

    override fun dismiss() {
        if (parentFragmentManager == null) return
        super.dismissAllowingStateLoss()
    }

    override fun onDestroy() {
        if (mDismissMethodAdded) {
            mDismissMethod?.run {
                invoke()
            }
        }
        super.onDestroy()
    }

    private fun getBaseView(): View? {
        return view
    }

    fun setFragmentManager(fragment: FragmentManager): BaseDialog {
        mFragment = fragment
        return this
    }

    /**
     * 设置dialog布局
     *
     * @param layoutRes Int
     * @return BaseDialog
     */
    fun setDialogView(@LayoutRes layoutRes: Int): BaseDialog {
        mLayoutRes = layoutRes
        arguments?.putInt("mLayoutRes", mLayoutRes)
        return this
    }

    /**
     * 设备dialog 宽高
     *
     * @param width Int
     * @param height Int
     * @return BaseDialog
     */
    fun setWindowSize(width: Int, height: Int): BaseDialog {
        setWidth(width)
        setHeight(height)
        return this
    }

    /**
     * 设置dialog 宽
     *
     * @param width Int
     * @return BaseDialog
     */
    fun setWidth(width: Int): BaseDialog {
        mWidth = width
        arguments?.putInt("mWidth", mWidth)
        return this
    }


    /**
     * 设置dialog  高
     *
     * @param height Int
     * @return BaseDialog
     */
    fun setHeight(height: Int): BaseDialog {
        mHeight = height
        arguments?.putInt("mHeight", mHeight)
        return this
    }

    /**
     * 设置dialog 动画效果
     *
     * @param animStyle Int
     * @return BaseDialog
     */
    fun setAnimStyle(@StyleRes animStyle: Int): BaseDialog {
        mAnimRes = animStyle
        arguments?.putInt("mAnimRes", mAnimRes)
        return this
    }

    /**
     *设置dialog 标题
     *
     * @param title String
     * @return BaseDialog
     */
    fun setTitle(title: String): BaseDialog {
        mTitle = title
        arguments?.putString("mTitle", mTitle)
        return this
    }


    /**
     * 设置dialog  左边标题，默认false为中间标题
     *
     * @param leftTitle Boolean
     * @return BaseDialog
     */
    fun setLeftTitle(leftTitle: Boolean): BaseDialog {
        mLeftTitle = leftTitle
        arguments?.putBoolean("mLeftTitle", mLeftTitle)
        return this
    }

    /**
     * 设置dialog  显示信息
     *
     * @param message String
     * @return BaseDialog
     */
    fun setMessage(message: String): BaseDialog {
        mMessage = message
        arguments?.putString("mMessage", mMessage)
        return this
    }


    /**
     * 设置dialog  点击取消按钮是否执行回调方法
     *
     * @param negativeToDismiss Boolean true 直接消失 false 执行回调方法
     * @return BaseDialog
     */
    fun setNegativeToDismiss(negativeToDismiss: Boolean): BaseDialog {
        mNegativeToDismiss = negativeToDismiss
        arguments?.putBoolean("mNegativeToDismiss", mNegativeToDismiss)
        return this
    }

    /**
     * 设置dialog  点击其他位置dialog消失
     *
     * @param canceledOnTouchOutside Boolean
     * @return BaseDialog
     */
    fun setCanceledOnTouchOutside(canceledOnTouchOutside: Boolean): BaseDialog {
        mCanceledOnTouchOutside = canceledOnTouchOutside
        arguments?.putBoolean("mCanceledOnTouchOutside", mCanceledOnTouchOutside)
        return this
    }


    /**
     * dialog 初始化要显示的内容
     *
     * @param buildMethod Function2<Dialog?, View?, Unit>
     * @return BaseDialog
     */
    fun setBuildMethod(buildMethod: (Dialog?, View?) -> Unit): BaseDialog {
        mBuildMethod = buildMethod
        arguments?.putBoolean("mBuildMethodAdded", true)
        return this
    }

    /**
     * dialog  消失的回调
     *
     * @param dismissMethod Function0<Unit>
     * @return BaseDialog
     */
    fun setDismissMethod(dismissMethod: () -> Unit): BaseDialog {
        mDismissMethod = dismissMethod
        arguments?.putBoolean("mDismissMethodAdded", true)
        return this
    }

    /**
     * 设置dialog 点击取消按钮的回调
     *
     * @param negativeButtonMethod Function2<Dialog?, View?, Unit>
     * @return BaseDialog
     */
    fun setNegativeButtonMethod(negativeButtonMethod: (Dialog?, View?) -> Unit): BaseDialog {
        mNegativeButtonMethod = negativeButtonMethod
        arguments?.putBoolean("mNegativeButtonMethodAdded", true)
        return this
    }

    /**
     * 设置dialog 点击确定按钮的回调
     *
     * @param positiveButtonMethod Function2<Dialog?, View?, Unit>
     * @return BaseDialog
     */
    fun setPositiveButtonMethod(positiveButtonMethod: (Dialog?, View?) -> Unit): BaseDialog {
        mPositiveButtonMethod = positiveButtonMethod
        arguments?.putBoolean("mPositiveButtonMethodAdded", true)
        return this
    }


    /**
     * 设置dialog  单独确定按钮  或者 双按钮
     *
     * @param negativeVis Boolean  默认false  双按钮 ，true 单按钮
     * @return BaseDialog
     */
    fun setVisibilityBtnDialogCancel(negativeVis: Boolean): BaseDialog {
        mNegativeVis = negativeVis
        arguments?.putBoolean("mNegativeVis", mNegativeVis)
        return this
    }

    fun show() {
        mFragment?.let {
            val ft = it.beginTransaction()
            try {
                val cls = DialogFragment::class.java
                val mDismissed = cls.getDeclaredField("mDismissed")
                mDismissed.isAccessible = true
                mDismissed[this] = false
                val mShownByMe = cls.getDeclaredField("mShownByMe")
                mShownByMe.isAccessible = true
                mShownByMe[this] = true
            } catch (e: Exception) {
                super.show(ft, BASE_DIALOG_TAG)
                return
            }
            val prev = it.findFragmentByTag(BASE_DIALOG_TAG)
            if (prev != null) {
                ft.commit()
            }
            ft.add(this, BASE_DIALOG_TAG)
            ft.commitAllowingStateLoss()
        }
    }
}



